home *** CD-ROM | disk | FTP | other *** search
- TYPE
- _stkchk(R),_stkfree(R) - Miscellaneous
-
- NAME
- _stkchk - check for stack overflow
- _stkfree - unwind dynamic stack
-
- SYNOPSIS
- #pragma regcall(_stkchk(d0))
- void _stkchk(signed short frame_size)
-
- DESCRIPTION
- This module contains two functions:
-
- void stkchk ( stack_frame_size : register d0 )
- void stkfree ()
-
- The function stkchk() is called by code generated by the compiler
- (when compiling with the -bd option). The function stkfree() is
- private, and should never be called directly by user programs.
-
- Advantages
- ~~~~~~~~~~
- o Checks stack frame requirements (for local variables)--usually
- 'link'ed--before overflowing the stack (where a call to stkchk
- would have caused non-stack memory to be munged).
-
- o Dynamic stack sizing (if enabled). Allows stack hungry programs
- to continue running, until the program exits normally (or you
- run out of memory).
-
- o Compatible with RConfig's setjmp(),longjmp(), which don't
- bypass stkfree().
-
- Disadvantages
- ~~~~~~~~~~~~~
- o What disadvantages?!
-
- CONSTANTS
- MIN_STACK is the minimum amount of stack space that should be available
- and is currently set at 2768. This is not entirely arbitrary. The
- theoretical minimum is 72 bytes (saving registers for a context switch).
- However, a call to printf() can require 1K of stack [LIBSRC52]; processes
- that call dos.library need an additional 1500 bytes of stack [RKMLIB90];
- and we also use 4 bytes for a magic cookie to test if the stack has
- somehow overflowed between calls--hopefully, the extra 192 bytes provides
- a safe margin. Feel free to increase this for your application.
-
- STACK_SIZE is the amount of additional stack space that should be
- allocated (if the existing stack will overflow). Currently set to 8192,
- this value should be larger than MIN_STACK.
-
- CONTEXT_SIZE is the amount of stack info that should be copied from a
- stack to the extension stack. This is due to stack buffers not being
- linked contiguously. At minimum, this is the largest amount pushed
- onto the stack for a procedure call. Obviously, the larger the context,
- the longer it takes to copy it.
-
- Note: These values should all be even numbers (evenly divisible by 2),
- to keep the stack "word aligned".
-
-
- SOURCE COMMENTS
- 1) __stkchk:
- ...
- lea CONTEXT_SIZE+8(a7),a1
- ...
- pea __stkfree#
-
- The '8' is the offset to the context on the stack. We skip the
- return address (that stkchk will return to); we also skip the return
- address that the calling procedure will return to when it ends, and
- replace it with the address to stkfree. So, when the calling
- procedure ends (and unwinds the stack), stkfree is called to free
- the extension stack buffer.
-
- 2) move.l __savsp,a1
- ...
- bra.s copynextword
-
- The main purpose of the code is this section is to avoid reading
- (too far) beyond a program's stack. In addition, this has the
- benefit of avoiding Enforcer hits in the case where a program's
- stack is located at the upper boundary of physical memory, reading
- beyond the bottom of the stack would be accessing nonexistent memory.
-
- 3) __stkfree:
- ...
- jsr __free
- addq.l #8,a7
-
- This pops the pointer (to the empty stack) used to setup the free()
- call. Also, pop the original return address when stkchk was called
- that allocated this stack buffer--stkchk returned using this address
- on the extension stack buffer.
-
- ERRORS
- Q) My program crashes even with DynaStack.
- A) And that's my fault? :-)
-
- Try increasing MIN_STACK, CONTEXT_SIZE, or your CLI's STACK. Make
- sure you have DYNASTACK defined when you re-assemble. Also, don't
- fiddle with the stack contents, beyond what would normally be visible
- (in scope) to your procedure.
-
- Q) I ported <some gnu_program_name> and it doesn't work with DynaStack.
- A) It's likely that it uses alloca() [in alloca.c], which allocates
- temporary storage based on the stack pointer. Because DynaStack
- buffers aren't continguous (or ordered in memory), GNU alloca() may
- be freeing memory that it shouldn't...yet. Try recompiling it
- without DynaStack.
-
- [ Personally, I'd recommend that you scrap GNU alloca() altogether,
- as memory may not be freed in a timely manner--the stack pointer
- isn't always the same upon entry to C functions at the same
- activation level, varying with the number of parameters pushed
- on to the stack and the size of the stack frame for local
- variables. If you really want an alloca() function, I have one
- available...and it works with DynaStack. ]
-
-
- REFERENCES
- LIBSRC52 - Manx Software Systems, Inc. Files: "stdio/format.c",
- "stdio/_format.c", and "sysio/stkchk.a68" from Manx's
- Aztec C Library Source (5.2a distribution for the Amiga),
- November 1991.
-
- RKMLIB90 - Commodore-Amiga, Inc. Amiga ROM Kernel Reference Manual:
- Libraries & Devices (for V1.3), p 268, 1990.
-